/*
 * =====================================================================================
 *
 *       Filename:  client.cpp
 *
 *    Description:  tcp的客户端
 *
 *        Version:  1.0
 *        Created:  2008年09月17日 13时40分38秒
 *       Revision:  none
 *       Compiler:  g++
 *
 *         Author:  ZhixiongHong (hzx), fishwarter@gmail.com
 *        Company:  Unioncast
 *
 * =====================================================================================
 */
#include "cs_common.h"

int main(int argc, char** argv)
{
	pid_t		pid;
	char 		request[MAXLINE], reply[MAXN];
	if( argc != 6 )
	{
		cout << "usage: client <hostname or ipstr><port><#children>"
			<< "<#loops/child><#bytes/request>" << endl;
		return -1;
	}

	int nChildren = atoi(argv[3]); // 子进程数目
	int	nLoops = atoi(argv[4]); // 发送次数
	int nBytes = atoi(argv[5]);
	unsigned short nPort = (unsigned short)atoi(argv[2]);
	snprintf(request, sizeof(request), "%d\n", nBytes);

	struct sockaddr_in	servaddr;	
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(nPort);
	servaddr.sin_addr.s_addr = inet_addr(argv[1]);
	cout << "fork " << nChildren << " processes and " << nLoops << " loops send " << nBytes << " bytes" << endl;
	for(int i = 0; i < nChildren; i++) 
	{
		if( (pid = fork()) == 0 ) /* child */
		{
			for(int j = 0; j < nLoops; j++)	
			{
				int clientSK = socket(AF_INET, SOCK_STREAM, 0);	
				if( clientSK < 0 )
				{
					cout << "can't create a socket, error = " <<strerror(errno)  << endl;
					continue;
				}
				int retInt = connect(clientSK, (sockaddr *)&servaddr, sizeof(sockaddr));
				if( retInt != 0)
				{
					cout << "connect to svr "<< argv[1] << ":" << nPort << ", error = " << strerror(errno) << endl;
					continue; 
				}
				
				send(clientSK, request, nBytes, 0);
				ssize_t	 n = recv(clientSK, reply, nBytes, 0);
				if( n != nBytes)
				{
					cout << "server returned " << n <<" byptes" << endl;
				}
				reply[nBytes] = '\0';
				cout << "server return: " << reply << " len=" << nBytes << endl;
				close(clientSK);
			}
			cout << "child  " << i << " done" << endl;
			exit(0);
		}	
	}
	while( wait(NULL) > 0)
		;
	if( errno != ECHILD)
		cout << "wait error " << endl;
	return 0;
}


